#include "footballtable.h"
#include <iostream>
#include <algorithm>


typedef std::map<std::string, TeamResult>::iterator map_iter;
typedef std::vector<std::pair<std::string, TeamResult>>::iterator vect_iter;


FootballTable::FootballTable(const std::vector<std::string> &teams) {
	for (const std::string &team : teams)
		_table[team] = TeamResult();
}


void FootballTable::print() {
    std::vector<std::pair<std::string, TeamResult>> outTable;

    for (map_iter i = _table.begin(); i != _table.end(); i++)
        outTable.push_back(*i);

    std::sort(outTable.begin(), outTable.end(), _compare);

    for (vect_iter i = outTable.begin(); i != outTable.end(); i++)
        std::cout << i->first << " " << i->second.win << " " << i->second.draw <<
		             " " << i->second.lose << " " << i->second.score << " " <<
		             i->second.scored - i->second.miss << std::endl;
}


void FootballTable::print(const std::string &team) {
    if (_table.find(team) == _table.end())
        std::cout << -1 << std::endl;
    std::cout << _table[team].win << " " << _table[team].draw << " " << _table[team].lose <<
	             " " << _table[team].score << " " << _table[team].scored - _table[team].miss << std::endl;
}


bool FootballTable::push(const std::string &matchResult) {
    Match result = _parseString(matchResult);

    bool isCorrectFirstTeam = _table.find(result.team1) != _table.end();
    bool isCorrectSecondTeam = _table.find(result.team2) != _table.end();

    if (!isCorrectFirstTeam || !isCorrectSecondTeam)
        return false;

	if (result.goalsTeam1 > result.goalsTeam2) {
		// Team 1 is win
		_table[result.team1].score += _WIN_SCORE;
		_table[result.team1].win++;
		_table[result.team2].lose++;
	} else if (result.goalsTeam1 < result.goalsTeam2) {
		// Team 2 is win
		_table[result.team2].score += _WIN_SCORE;
		_table[result.team1].lose++;
		_table[result.team2].win++;
	} else {
		// Draw
        _table[result.team1].score += _DRAW_SCORE;
        _table[result.team2].score += _DRAW_SCORE;
		_table[result.team1].draw++;
		_table[result.team2].draw++;
    }

	_table[result.team1].scored += result.goalsTeam1;
	_table[result.team1].miss += result.goalsTeam2;
	_table[result.team2].scored += result.goalsTeam2;
	_table[result.team2].miss += result.goalsTeam1;

    return true;
}


bool FootballTable::push(const std::string &team1,
                         const int goalsTeam1,
                         const std::string &team2,
                         const int goalsTeam2
                         ) {
    bool isCorrectFirstTeam = _table.find(team1) != _table.end();
    bool isCorrectSecondTeam = _table.find(team2) != _table.end();

    if (!isCorrectFirstTeam || !isCorrectSecondTeam)
        return false;

	if (goalsTeam1 > goalsTeam2) {
		// Team 1 is win
		_table[team1].score += _WIN_SCORE;
		_table[team1].win++;
		_table[team2].lose++;
	} else if (goalsTeam1 < goalsTeam2) {
		// Team 2 is win
		_table[team2].score += _WIN_SCORE;
		_table[team1].lose++;
		_table[team2].win++;
	} else {
		// Draw
		_table[team1].score += _DRAW_SCORE;
		_table[team2].score += _DRAW_SCORE;
		_table[team1].draw++;
		_table[team2].draw++;
    }

	_table[team1].scored += goalsTeam1;
	_table[team1].miss += goalsTeam2;
	_table[team2].scored += goalsTeam2;
	_table[team2].miss += goalsTeam1;

    return true;
}


Match FootballTable::_parseString(std::string str) {
    // team1 1:2 team2
    Match result;
    for (size_t i = 0; i < str.find(" "); i++)
        result.team1 += str[i];

    str.erase(0, str.find(" ") + 1);

    for (size_t i = 0; i < str.find(":"); i++)
        result.goalsTeam1 = result.goalsTeam1 * 10 + str[i] - 48;

    str.erase(0, str.find(":") + 1);

    for (size_t i = 0; i < str.find(" "); i++)
        result.goalsTeam2 = result.goalsTeam2 * 10 + str[i] - 48;

    str.erase(0, str.find(" ") + 1);

    for (size_t i = 0; i < str.length(); i++)
        result.team2 += str[i];

    return result;
}


bool FootballTable::_compare(const std::pair<std::string, TeamResult> &p1,
                             const std::pair<std::string, TeamResult> &p2
                             ) {
    return p1.second.score > p2.second.score;
}


int FootballTable::getScore(const std::string &team) {
    return _table[team].score;
}


bool FootballTable::addTeam(const std::string &team) {
    if (_table.find(team) != _table.end())
        return false;

	_table[team].win = 0;
	_table[team].lose = 0;
	_table[team].draw = 0;
	_table[team].score = 0;
	_table[team].scored = 0;
	_table[team].miss = 0;

    return true;
}
